package com.web_bloks.http.client;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;

import com.google.gwt.http.client.Response;

import java.util.Set;
import java.util.Iterator;
import java.util.HashMap;

import com.web_bloks.system.client.Logger;

/**
 * HttpCall
 * Because HTTPRequest does not support headers.
 * 
 * One 'RequestCallback' listener can be registered.
 * 
 * @author Jean-Lou Dupont
 *
 */
public class HttpCall implements RequestCallback {

	public final static int DEFAULT_TIMEOUT = 5000; //5secs.
	
	Request request = null;
	RequestBuilder.Method method = null;
	
	int timeout = 0;
	String user = null;
	String password = null;
		
	HashMap<String,String> headers = null;
	
	RequestCallback callback = null;
	
	/*===================================================================
	 * CONSTRUCTORS 
	 ===================================================================*/
	
	public HttpCall() {
		method = RequestBuilder.GET;
	}
	public HttpCall(RequestBuilder.Method m) {
		method = m;
	}
	
	/*===================================================================
	 * PUBLIC 
	 ===================================================================*/
	
	public void setTimeoutMillis(int timeout) {
		this.timeout = timeout;
	}
	
	public void setUser(String user) {
		this.user = new String( user );
	}
	
	public void setPassword(String password) {
		this.password = new String( password );
	}
	
	public void setHeader(String name, String value) {
		if ( headers == null )
			headers = new HashMap<String,String>();
		//Logger.logInfo( thisClass+".setHeader: name=["+name+"]");
		this.headers.put( name, value );
	}
	
	public void setRequestCallback(RequestCallback cb) {
		this.callback = cb;
	}
	
	public void clearHeaders() {
		headers = null;
	}
	/**
	 * Executes the request
	 * 
	 * @param url
	 * @param data
	 * @throws RequestException
	 */
	public void execute(String url, String data) 
		throws RequestException {
		//Logger.logInfo( thisClass+".execute: url=["+url+"]");
		
		if (url == null || url.length()==0)
			throw new RequestException(this.getClass()+".execute: url can't be null/empty");
		
		RequestBuilder rb = new RequestBuilder(method, url);

		String name = null;
		String value = null;
		
		if (headers != null) {
			
			Set<String> entries = headers.keySet();
			Iterator<String> iter = entries.iterator();
			
			// BUILD HEADER
			while( iter.hasNext() ) {
				
				name = (String) iter.next();
				value = (String) headers.get(name);
				
				if ( (value != null) && (value.length()!=0))
					rb.setHeader(name, value);
			}
		}
		if (user != null)
			rb.setUser(user);
		
		if (password != null)
			rb.setPassword(password);
		
		if (timeout == 0)
			rb.setTimeoutMillis(DEFAULT_TIMEOUT);
		else
			rb.setTimeoutMillis(timeout);
		
		// SEND
		request = rb.sendRequest(data, this);
		
	}
	/**
	 * TODO does this trigger an 'onError' ?
	 */
	public void cancel() {
		if (request != null)
			request.cancel();
	}
	public boolean isPending() {
		if ( request != null )
			return request.isPending();
		
		return false;
	}
	
	/*========================================================
	 * REQUESTCALLBACK
	 ========================================================*/
	public void onError(Request request, java.lang.Throwable exception ) {
		Logger.logInfo( this.getClass()+".onError");
		if (callback != null)
			this.callback.onError(request, exception);
		this.request = null;
	}
	
	public void onResponseReceived(Request request, Response response) {
		int code = response.getStatusCode();
		
		Logger.logInfo( this.getClass()+".onResponseReceived, code=" + code);		
		if (callback != null) {
			
			if (code == 200)
				this.callback.onResponseReceived(request, response);
			else
				this.callback.onError(request, null);
		}
			
		this.request = null;
	}
	
}//END
